package org.wsocket.flashbridge;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.ServerSocket;
import java.net.Socket;

import org.apache.log4j.Logger;

public class FlashBridge {
    private static Logger log=Logger.getLogger(FlashBridge.class);
    private ServerSocket serverSocket = null;
    private int listenerPort = 843;
    private boolean isRunning = false;
    private Thread bridgeThread = null;
    private int TIMEOUT = 2500;

    public FlashBridge() {
        if (log.isDebugEnabled()) {
            log.debug("Starting flash bridge...");
        }
        try {
            serverSocket = new ServerSocket(listenerPort);
            BridgeListener listener = new BridgeListener();
            bridgeThread = new Thread(listener);
            bridgeThread.start();
        } catch (IOException ex) {
            log.info("flash bridge started." + ex.getMessage());
        }
        if (log.isInfoEnabled()) {
            log.info("flash bridge started.");
        }
    }

    private class BridgeListener implements Runnable {

        @Override
        public void run() {

            isRunning = true;
            while (isRunning) {
                try {
                    // accept is blocking so here is no need
                    // to put any sleeps into the loop
                    // if (log.isDebugEnabled()) {
                    // log.debug("Waiting on flash policy-file-request...");
                    // }
                    Socket clientSocket = serverSocket.accept();
                    // if (log.isDebugEnabled()) {
                    // log.debug("Client connected...");
                    // }
                    try {
                        clientSocket.setSoTimeout(TIMEOUT);
                        InputStreamReader isr = new InputStreamReader(
                            clientSocket.getInputStream(), "UTF-8");
                        PrintStream os = new PrintStream(clientSocket
                            .getOutputStream(), true, "UTF-8");

                        char[] ca = new char[1024];
                        String lLine = "";
                        int lLen;
                        // TODO: implement timeout if anyone plays on port 843!
                        do {
                            lLen = isr.read(ca);
                            if (lLen > 0) {
                                lLine += new String(ca, 0, lLen);
                            } else {
                                Thread.sleep(10);
                            }
                        } while (lLen >= 0
                            && lLine.indexOf("<policy-file-request/>") < 0);
                        log.debug("Answering on flash policy-file-request ("
                            + lLine + ")...");
                        os
                            .print("<cross-domain-policy>"
                                + "<allow-access-from domain=\"*\" to-ports=\"*\" />"
                                + "</cross-domain-policy>\n");
                    } catch (UnsupportedEncodingException ex) {
                        log.error("(encoding) " + ex.getClass().getSimpleName()
                            + ": " + ex.getMessage());
                    } catch (IOException ex) {
                        log.error("(io) " + ex.getClass().getSimpleName()
                            + ": " + ex.getMessage());
                    } catch (Exception ex) {
                        log.error("(other) " + ex.getClass().getSimpleName()
                            + ": " + ex.getMessage());
                    }

                    clientSocket.close();
                    if (log.isDebugEnabled()) {
                        log.debug("Client disconnected...");
                    }
                } catch (Exception ex) {
                    isRunning = false;
                    log.error("(accept) " + ex.getClass().getSimpleName()
                        + ": " + ex.getMessage());
                }
            }
        }
    }
}
